
#include<iostream>
#include<list>
using namespace std;

class Observer	//观察者
{
public:
	virtual ~Observer() {}
	virtual void Update(int) = 0;
};

class Subject	//目标
{
public:
	virtual ~Subject() {}
	virtual void Attach(Observer*) = 0;
	virtual void Detach(Observer*) = 0;
	virtual void Notify() = 0;
};

class ConcreteObserver : public Observer	//具体观察者
{
private:
	Subject* _pSubject;

public:
	ConcreteObserver(Subject* pSubject) : _pSubject(pSubject)
	{
		//在目标中注册当前观察者
		//(此处的观察者是广义上的观察者，目标并不知道具体谁要观察它，目标只进行广播即可)
		this->_pSubject->Attach(this);
		cout << "I'm the observer \" 1 \"。" << endl;
	}	

	void Update(int value) override
	{
		cout << "ConcreteObserver get the updata.New State: " << value << endl;
	}
};

class ConcreteObserver2 : public Observer	//具体观察者
{
private:
	Subject* _pSubject;

public:
	ConcreteObserver2(Subject* pSubject) :_pSubject(pSubject)
	{
		this->_pSubject->Attach(this);
		cout << "I'm the observer \"2\" 。" << endl;
	}

	void Update(int value) override
	{
		cout << "ConcreteObserver2 get the update.New State: " << value << endl;
	}
};

class ConcreteSubject :public Subject	//具体目标
{
private:
	list<Observer*> _pObserverList;
	int _iState;

public:
	void SetState(int state)
	{
		_iState = state;
	}

	void Attach(Observer* pObserver) override
	{
		_pObserverList.push_back(pObserver);
	}

	void Detach(Observer* pObserver) override
	{
		_pObserverList.remove(pObserver);
	}

	void Notify() override
	{
		auto begin = _pObserverList.begin();
		auto end = _pObserverList.end();
		while (begin != end)
		{
			(*begin)->Update(_iState);
			begin++;
		}
	}
};




int main()
{
	//创建目标
	ConcreteSubject* pSubject = new ConcreteSubject();

	//创建观察者
	Observer* pObserver = new ConcreteObserver(pSubject);
	Observer* pObserver2 = new ConcreteObserver2(pSubject);

	//改变当前状态
	pSubject->SetState(2);

	//广播给所有广义上的观察者
	pSubject->Notify();

	//去除某个观察者
	pSubject->Detach(pObserver);

	//改变当前状态
	pSubject->SetState(3);

	//重新广播
	pSubject->Notify();

	//结束，释放对象
	delete pObserver;
	delete pObserver2;
	delete pSubject;
	return 0;
}

/*

I'm the observer " 1 "。
I'm the observer "2" 。
ConcreteObserver get the updata.New State: 2
ConcreteObserver2 get the update.New State: 2
ConcreteObserver2 get the update.New State: 3

*/












#include<iostream>
#include<list>
#include<string>
using namespace std;


//观察者模式有许多具有类似含义的不同术语，比如主题也成为发布者，观察者通常称为订阅者。
//动词“观察”“倾听”或“跟踪”通常表示相同的意思


class IObserver
{
public:
	virtual ~IObserver() {}
	virtual void Update(const string& messageFromSubject) = 0;
};


class ISubject
{
public:
	virtual ~ISubject() {}
	virtual void Attach(IObserver* observer) = 0;
	virtual void Detach(IObserver* observer) = 0;
	virtual void Notify() = 0;
};

//具体目标拥有一些重要的状态，并在状态更改时通知观察者
class Subject : public ISubject
{
private:
	list<IObserver *> _listObserver;
	string _message;
public:
	virtual ~Subject()
	{
		cout << "Goodbye, I was the Subject。" << endl;
	}

	//定义订阅管理方法
	void Attach(IObserver* observer) override
	{
		_listObserver.push_back(observer);
	}

	void Detach(IObserver* observer) override
	{
		_listObserver.remove(observer);
	}

	void Notify() override
	{
		list<IObserver *>::iterator begin = _listObserver.begin();
		HowMangObserver();
		while (begin != _listObserver.end())
		{
			(*begin)->Update(_message);
			++begin;
		}
	}

	void CreateMessage(string message = "Empty")
	{
		this->_message = message;
		Notify();
	}

	void HowMangObserver()
	{
		cout << "There are " << _listObserver.size() << "observers in the list ." << endl;
	}
	
	//通常的来说，订阅逻辑知识主题真正能做的事情的一小部分。
	//主题通常拥有一些重要的业务逻辑，每当重要的事情即将发生（或者发生之后）时触发通知方法。
	
	void SomeBusinessLogic()
	{
		this->_message = "change message message";
		Notify();
		cout << "I'm about to do some thing important。" << endl;
	}
};


class Observer :public IObserver
{
private:
	string _messageFromSubjcet;
	Subject& _subject;
	static int _staticNumber;
	int _number;

public:
	Observer(Subject& subject) :_subject(subject)
	{
		this->_subject.Attach(this);
		cout << "Hi, I'm the Observer。" << ++Observer::_staticNumber << "\"." << endl;
		this->_number = Observer::_staticNumber;
	}

	~Observer()
	{
		cout << "Goodbye, I was the Observer \"" << this->_number << "\"" << endl;
	}

	void Update(const string& messageFromSubject) override
	{
		this->_messageFromSubjcet = messageFromSubject;
		PrintInfo();
	}

	void RemoveMeFromTheList()
	{
		this->_subject.Detach(this);
		cout << "Observer \"" << this->_number << "\" remove from the list." << endl;
	}

	void PrintInfo()
	{
		cout << "Observer \"" << this->_number << "\" : a new message is aviliable -->"
			<< this->_messageFromSubjcet << endl;
	}

};

int Observer::_staticNumber = 0;

void ClientCode()
{
	Subject* subject = new Subject();
	Observer* observer1 = new Observer(*subject);
	Observer* observer2 = new Observer(*subject);
	Observer* observer3 = new Observer(*subject);
	Observer* observer4; 
	Observer* observer5;

	subject->CreateMessage("hello world! :D");
	observer3->RemoveMeFromTheList();

	subject->CreateMessage("The weather is hot today! ;p");
	observer4 = new Observer(*subject);

	observer2->RemoveMeFromTheList();
	observer5 = new Observer(*subject);
	observer4->RemoveMeFromTheList();
	observer1->RemoveMeFromTheList();

	delete observer5;
	delete observer4;
	delete observer3;
	delete observer2;
	delete observer1;
	delete subject;

}

int main()
{
	ClientCode();
	return 0;
}



/*
Hi, I'm the Observer。1".
Hi, I'm the Observer。2".
Hi, I'm the Observer。3".
There are 3observers in the list .
Observer "1" : a new message is aviliable -->hello world! :D
Observer "2" : a new message is aviliable -->hello world! :D
Observer "3" : a new message is aviliable -->hello world! :D
Observer "3" remove from the list.
There are 2observers in the list .
Observer "1" : a new message is aviliable -->The weather is hot today! ;p
Observer "2" : a new message is aviliable -->The weather is hot today! ;p
Hi, I'm the Observer。4".
Observer "2" remove from the list.
Hi, I'm the Observer。5".
Observer "4" remove from the list.
Observer "1" remove from the list.
Goodbye, I was the Observer "5"
Goodbye, I was the Observer "4"
Goodbye, I was the Observer "3"
Goodbye, I was the Observer "2"
Goodbye, I was the Observer "1"
Goodbye, I was the Subject。
*/







